using System;
using System.Collections.Generic;
using UnityEngine;

namespace PKGames.AssetLoader
{
	[Serializable]
	public class AssetQueue
	{
		[SerializeField]
		private int _requestExecutionLimit;

		private Queue<AssetRequest> _requests;

		private Queue<AssetRequest> _pendingRequests;

		private MonoBehaviour _owner;

		public Action<AssetRequest> OnRequestFinished;

		private string Tag => "[AssetQueue] ";

		public void Setup(MonoBehaviour owner)
		{
			_owner = owner;
			_requests = new Queue<AssetRequest>();
			_pendingRequests = new Queue<AssetRequest>();
		}

		public void Add(AssetRequest request)
		{
			_pendingRequests.Enqueue(request);
			UnityEngine.Debug.Log(Tag + "Added " + request);
		}

		public void Pause()
		{
			foreach (AssetRequest request in _requests)
			{
				request.Pause();
			}
		}

		public void Resume()
		{
			foreach (AssetRequest request in _requests)
			{
				request.Resume();
			}
		}

		public void Clear()
		{
			foreach (AssetRequest request in _requests)
			{
				request.Cancel();
			}
			foreach (AssetRequest pendingRequest in _pendingRequests)
			{
				pendingRequest.Cancel();
			}
			_pendingRequests.Clear();
		}

		public void Update()
		{
			if (_pendingRequests.Count > 0 && _requests.Count < _requestExecutionLimit)
			{
				AssetRequest assetRequest = _pendingRequests.Dequeue();
				_requests.Enqueue(assetRequest);
				AssetRequest assetRequest2 = assetRequest;
				assetRequest2.OnFinished = (Action<AssetRequest>)Delegate.Combine(assetRequest2.OnFinished, new Action<AssetRequest>(OnFinished));
				_owner.StartCoroutine(assetRequest.Execute());
			}
		}

		private void OnFinished(AssetRequest assetRequest)
		{
			UnityEngine.Debug.Log(Tag + "AssetRequest finished: " + assetRequest);
			OnRequestFinished.Fire(assetRequest);
			_requests.Dequeue();
		}

		public T GetRequest<T>(string id) where T : AssetRequest
		{
			foreach (AssetRequest request in _requests)
			{
				if (request.Id == id)
				{
					return request as T;
				}
			}
			foreach (AssetRequest pendingRequest in _pendingRequests)
			{
				if (pendingRequest.Id == id)
				{
					return pendingRequest as T;
				}
			}
			return (T)null;
		}
	}
}
